home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / mkobj.c < prev    next >
C/C++ Source or Header  |  1993-01-18  |  18KB  |  762 lines

  1. /*    SCCS Id: @(#)mkobj.c    3.1    93/01/17    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "artifact.h"
  7. #include "prop.h"
  8.  
  9. STATIC_DCL void FDECL(mkbox_cnts,(struct obj *));
  10.  
  11. struct icp {
  12.     int  iprob; /* probability of an item type */
  13.     char ilet;    /* item class */
  14. };
  15.  
  16. #ifdef OVL1
  17.  
  18. const struct icp mkobjprobs[] = {
  19. {10, WEAPON_CLASS},
  20. {10, ARMOR_CLASS},
  21. {20, FOOD_CLASS},
  22. { 8, TOOL_CLASS},
  23. { 8, GEM_CLASS},
  24. {16, POTION_CLASS},
  25. {16, SCROLL_CLASS},
  26. { 4, SPBOOK_CLASS},
  27. { 4, WAND_CLASS},
  28. { 3, RING_CLASS},
  29. { 1, AMULET_CLASS}
  30. };
  31.  
  32. const struct icp boxiprobs[] = {
  33. {18, GEM_CLASS},
  34. {15, FOOD_CLASS},
  35. {18, POTION_CLASS},
  36. {18, SCROLL_CLASS},
  37. {12, SPBOOK_CLASS},
  38. { 7, GOLD_CLASS},
  39. { 6, WAND_CLASS},
  40. { 5, RING_CLASS},
  41. { 1, AMULET_CLASS}
  42. };
  43.  
  44. #ifdef REINCARNATION
  45. const struct icp rogueprobs[] = {
  46. {12, WEAPON_CLASS},
  47. {12, ARMOR_CLASS},
  48. {22, FOOD_CLASS},
  49. {22, POTION_CLASS},
  50. {22, SCROLL_CLASS},
  51. { 5, WAND_CLASS},
  52. { 5, RING_CLASS}
  53. };
  54. #endif
  55.  
  56. const struct icp hellprobs[] = {
  57. {20, WEAPON_CLASS},
  58. {20, ARMOR_CLASS},
  59. {16, FOOD_CLASS},
  60. {12, TOOL_CLASS},
  61. {10, GEM_CLASS},
  62. { 1, POTION_CLASS},
  63. { 1, SCROLL_CLASS},
  64. { 8, WAND_CLASS},
  65. { 8, RING_CLASS},
  66. { 4, AMULET_CLASS}
  67. };
  68.  
  69. static int NEARDATA mksx=0, NEARDATA mksy=0;
  70.  
  71. struct obj *
  72. mkobj_at(let,x,y, artif)
  73. char let;
  74. int x,y;
  75. boolean artif;
  76. {
  77.     register struct obj *otmp;
  78.  
  79.     mksx = x; mksy = y;
  80.     /* We need to know the X, Y coordinates while creating the object,
  81.      * to insure shop boxes are empty.
  82.      * Yes, this is a horrible kludge...
  83.      */
  84.     otmp = mkobj(let,artif);
  85.     otmp->nobj = fobj;
  86.     fobj = otmp;
  87.     place_object(otmp, x, y);
  88.     mksx = mksy = 0;
  89.     return(otmp);
  90. }
  91.  
  92. struct obj *
  93. mksobj_at(otyp,x,y,init)
  94. int otyp,x,y;
  95. boolean init;
  96. {
  97.     register struct obj *otmp;
  98.  
  99.     mksx = x; mksy = y;
  100.     otmp = mksobj(otyp,init,TRUE);
  101.     otmp->nobj = fobj;
  102.     place_object(otmp, x, y);
  103.     mksx = mksy = 0;
  104.     return((fobj = otmp));
  105. }
  106.  
  107. struct obj *
  108. mkobj(let, artif)
  109. char let;
  110. boolean artif;
  111. {
  112.     register int tprob, i, prob = rnd(1000);
  113.  
  114.     if(let == RANDOM_CLASS) {
  115.         const struct icp *iprobs =
  116. #ifdef REINCARNATION
  117.                     (Is_rogue_level(&u.uz)) ?
  118.                     (const struct icp *)rogueprobs :
  119. #endif
  120.                     Inhell ? (const struct icp *)hellprobs :
  121.                     (const struct icp *)mkobjprobs;
  122.  
  123.         for(tprob = rnd(100);
  124.             (tprob -= iprobs->iprob) > 0;
  125.             iprobs++);
  126.         let = iprobs->ilet;
  127.     }
  128.  
  129.     i = bases[letindex(let)];
  130.     while((prob -= objects[i].oc_prob) > 0) i++;
  131.  
  132.     if(objects[i].oc_class != let || !OBJ_NAME(objects[i]))
  133.         panic("probtype error, let=%c i=%d", let, i);
  134.  
  135.     return(mksobj(i, TRUE, artif));
  136. }
  137.  
  138. STATIC_OVL void
  139. mkbox_cnts(box)
  140. /* Note: does not check to see if it overloaded the box capacity; usually
  141.  * possible only with corpses in ice boxes.
  142.  */
  143. struct obj *box;
  144. {
  145.     register int n;
  146.     register struct obj *otmp, *gold = 0;
  147.  
  148.     box->cobj = (struct obj *) 0;
  149.  
  150.     switch(box->otyp) {
  151.         case ICE_BOX:        n = 20; break;
  152.         case CHEST:        n = 5; break;
  153.         case LARGE_BOX:        n = 3; break;
  154.         case SACK:
  155.         case OILSKIN_SACK:
  156.         case BAG_OF_HOLDING:    n = 1; break;
  157.         default:        n = 0; break;
  158.     }
  159.  
  160.     for (n = rn2(n+1); n > 0; n--) {
  161.         if (box->otyp == ICE_BOX) {
  162.         if (!(otmp = mksobj(CORPSE, TRUE, TRUE))) continue;
  163.         /* Note: setting age to 0 is correct.  Age has a different
  164.          * from usual meaning for objects stored in ice boxes. -KAA
  165.          */
  166.         otmp->age = 0L;
  167.         } else {
  168.         register int tprob;
  169.         const struct icp *iprobs = boxiprobs;
  170.  
  171.         for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++)
  172.             ;
  173.         if (!(otmp = mkobj(iprobs->ilet, TRUE))) continue;
  174.  
  175.         /* handle a couple of special cases */
  176.         if (otmp->otyp == GOLD_PIECE) {
  177.             /* 2.5 x level's usual amount; weight adjusted below */
  178.             otmp->quan = (long)(rnd(level_difficulty()+2) * rnd(75));
  179.             if (gold) {            /* gold already in this box */
  180.             gold->quan += otmp->quan;    /* merge */
  181.             dealloc_obj(otmp);    /* note: not yet in any chain */
  182.             continue;
  183.             } else {
  184.             gold = otmp;        /* remember this object */
  185.             }
  186.         } else while (otmp->otyp == ROCK) {
  187.             otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE);
  188.             if (otmp->quan > 2L) otmp->quan = 1L;
  189.             otmp->owt = weight(otmp);
  190.         }
  191.         if (box->otyp == BAG_OF_HOLDING) {
  192.             if (Is_mbag(otmp)) {
  193.             otmp->otyp = SACK;
  194.             otmp->spe = 0;
  195.             otmp->owt = weight(otmp);
  196.             } else while (otmp->otyp == WAN_CANCELLATION)
  197.                 otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
  198.         }
  199.         }
  200.         otmp->nobj = box->cobj;
  201.         box->cobj = otmp;
  202.     }
  203.     if (gold) gold->owt = weight(gold);    /* quantity was diddled */
  204.     return;
  205. }
  206.  
  207. int
  208. rndmonnum()    /* select a random, common monster type */
  209. {
  210.     register struct permonst *ptr;
  211.     register int    i;
  212.  
  213.     /* Plan A: get a level-appropriate common monster */
  214.     ptr = rndmonst();
  215.     if (ptr) return(monsndx(ptr));
  216.  
  217.     /* Plan B: get any common monster */
  218.     do {
  219.         ptr = &mons[(i = rn2(NUMMONS))];
  220.     } while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL)));
  221.  
  222.     return(i);
  223. }
  224.  
  225. #endif /* OVL1 */
  226. #ifdef OVLB
  227. const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS,
  228.              GEM_CLASS, SPBOOK_CLASS, WEAPON_CLASS, 0};
  229.  
  230. /*ARGSUSED*/
  231. struct obj *
  232. mksobj(otyp, init, artif)
  233. int otyp;
  234. boolean init;
  235. boolean artif;
  236. {
  237.     int tryct;
  238.     struct obj *otmp;
  239.     char let = objects[otyp].oc_class;
  240.  
  241.     otmp = newobj(0);
  242.     *otmp = zeroobj;
  243.     otmp->age = monstermoves;
  244.     otmp->o_id = flags.ident++;
  245.     otmp->quan = 1L;
  246.     otmp->oclass = let;
  247.     otmp->otyp = otyp;
  248.     otmp->dknown = index(dknowns, let) ? 0 : 1;
  249.     if (!objects[otmp->otyp].oc_uses_known)
  250.         otmp->known = 1;
  251.     if (init) switch (let) {
  252.     case WEAPON_CLASS:
  253.         otmp->quan = (otmp->otyp <= SHURIKEN) ? (long) rn1(6,6) : 1L;
  254.         if(!rn2(11)) {
  255.             otmp->spe = rne(3);
  256.             otmp->blessed = rn2(2);
  257.         } else if(!rn2(10)) {
  258.             curse(otmp);
  259.             otmp->spe = -rne(3);
  260.         } else    blessorcurse(otmp, 10);
  261.  
  262.         if (artif && !rn2(20))
  263.             otmp = mk_artifact(otmp, (aligntyp)A_NONE);
  264.         break;
  265.     case FOOD_CLASS:
  266.         otmp->oeaten = 0;
  267.         switch(otmp->otyp) {
  268.         case CORPSE:
  269.             /* overridden by mkcorpstat() */
  270.             do otmp->corpsenm = rndmonnum();
  271.             while (mons[otmp->corpsenm].geno & G_NOCORPSE);
  272.             break;
  273.         case EGG:
  274.             if(!rn2(3)) {        /* "live" eggs */
  275.             register struct permonst *ptr;
  276.             for(tryct = 0;
  277.                 (!(ptr = rndmonst()) ||
  278.                 (!lays_eggs(ptr) && ptr != &mons[PM_KILLER_BEE])) &&
  279.                 tryct < 100;
  280.                 tryct++);
  281.             if(tryct < 100)    otmp->corpsenm = monsndx(ptr);
  282.             else        otmp->corpsenm = -1; /* empty */
  283.             } else        otmp->corpsenm = -1; /* empty */
  284.             break;
  285.         case TIN:
  286.             if(!rn2(6)) {
  287.             otmp->spe = 1;        /* spinach */
  288.             otmp->corpsenm = -1;
  289.             } else do {
  290.             otmp->corpsenm = rndmonnum();
  291.             } while (mons[otmp->corpsenm].geno & G_NOCORPSE);
  292.             blessorcurse(otmp, 10);
  293.             break;
  294. #ifdef TUTTI_FRUTTI
  295.         case SLIME_MOLD:
  296.             otmp->spe = current_fruit;
  297.             break;
  298. #endif
  299.         }
  300.         if (otmp->otyp == CORPSE) break;
  301.         /* fall into next case */
  302.  
  303.     case GEM_CLASS:
  304.         if (otmp->otyp == LOADSTONE) curse(otmp);
  305.         else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6);
  306.         else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L;
  307.         else otmp->quan = 1L;
  308.         break;
  309.     case TOOL_CLASS:
  310.         switch(otmp->otyp) {
  311.         case TALLOW_CANDLE:
  312.         case WAX_CANDLE:    otmp->spe = 1;
  313.                     otmp->age = 20L * /* 400 or 200 */
  314.                           (long)objects[otmp->otyp].oc_cost;
  315.                     otmp->lamplit = 0;
  316.                     otmp->quan = 1L +
  317.                           (long)(rn2(2) ? rn2(7) : 0);
  318.                     blessorcurse(otmp, 5);
  319.                     break;
  320.         case BRASS_LANTERN:
  321.         case OIL_LAMP:        otmp->spe = 1;
  322.                     otmp->age = (long) rn1(500,1000);
  323.                     otmp->lamplit = 0;
  324.                     blessorcurse(otmp, 5);
  325.                     break;
  326.         case MAGIC_LAMP:    otmp->spe = 1;
  327.                     otmp->lamplit = 0;
  328.                     blessorcurse(otmp, 2);
  329.                     break;
  330.         case CHEST:
  331.         case LARGE_BOX:        otmp->olocked = !!(rn2(5));
  332.                     otmp->otrapped = !(rn2(10));
  333.         case ICE_BOX:
  334.         case SACK:
  335.         case OILSKIN_SACK:
  336.         case BAG_OF_HOLDING:    mkbox_cnts(otmp);
  337.                     break;
  338.         case MAGIC_MARKER:    otmp->spe = rn1(70,30);
  339.                     break;
  340.         case CAN_OF_GREASE:    otmp->spe = rnd(25);
  341.                     blessorcurse(otmp, 10);
  342.                     break;
  343.         case CRYSTAL_BALL:    otmp->spe = rnd(5);
  344.                     blessorcurse(otmp, 2);
  345.                     break;
  346.         case HORN_OF_PLENTY:
  347.         case BAG_OF_TRICKS:    otmp->spe = rnd(20);
  348.                     break;
  349.         case FIGURINE:    {    int tryct2 = 0;
  350.                     do
  351.                         otmp->corpsenm = rndmonnum();
  352.                     while(is_human(&mons[otmp->corpsenm])
  353.                         && tryct2++ < 30);
  354.                     blessorcurse(otmp, 4);
  355.                     break;
  356.                 }
  357.         case BELL_OF_OPENING:   otmp->spe = 3;
  358.                     break;
  359.         case MAGIC_FLUTE:
  360.         case MAGIC_HARP:
  361.         case FROST_HORN:
  362.         case FIRE_HORN:
  363.         case DRUM_OF_EARTHQUAKE:
  364.                     otmp->spe = rn1(5,4);
  365.                     break;
  366.         }
  367.         break;
  368.     case AMULET_CLASS:
  369.         if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION ||
  370.            otmp->otyp == AMULET_OF_CHANGE ||
  371.            otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
  372.             curse(otmp);
  373.         } else    blessorcurse(otmp, 10);
  374.     case VENOM_CLASS:
  375.     case CHAIN_CLASS:
  376.     case BALL_CLASS:
  377.         break;
  378.     case POTION_CLASS:
  379.     case SCROLL_CLASS:
  380. #ifdef MAIL
  381.         if (otmp->otyp != SCR_MAIL)
  382. #endif
  383.             blessorcurse(otmp, 4);
  384.         break;
  385.     case SPBOOK_CLASS:
  386.         blessorcurse(otmp, 17);
  387.         break;
  388.     case ARMOR_CLASS:
  389.         if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS ||
  390.            otmp->otyp == LEVITATION_BOOTS ||
  391.            otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT ||
  392.            otmp->otyp == GAUNTLETS_OF_FUMBLING ||
  393.            !rn2(11))) {
  394.             curse(otmp);
  395.             otmp->spe = -rne(3);
  396.         } else if(!rn2(10)) {
  397.             otmp->blessed = rn2(2);
  398.             otmp->spe = rne(3);
  399.         } else    blessorcurse(otmp, 10);
  400.         break;
  401.     case WAND_CLASS:
  402.         if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else
  403.         otmp->spe = rn1(5,
  404.             (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
  405.         blessorcurse(otmp, 17);
  406.         otmp->recharged = 0; /* used to control recharging */
  407.         break;
  408.     case RING_CLASS:
  409.         if(objects[otmp->otyp].oc_charged) {
  410.             blessorcurse(otmp, 3);
  411.             if(rn2(10)) {
  412.             if(rn2(10) && bcsign(otmp))
  413.                 otmp->spe = bcsign(otmp) * rne(3);
  414.             else otmp->spe = rn2(2) ? rne(3) : -rne(3);
  415.             }
  416.             /* make useless +0 rings much less common */
  417.             if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3);
  418.             /* negative rings are usually cursed */
  419.             if (otmp->spe < 0 && rn2(5)) curse(otmp);
  420.         } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION ||
  421. #ifdef POLYSELF
  422.               otmp->otyp == RIN_POLYMORPH ||
  423. #endif
  424.               otmp->otyp == RIN_AGGRAVATE_MONSTER ||
  425.               otmp->otyp == RIN_HUNGER || !rn2(9))) {
  426.             curse(otmp);
  427.         }
  428.         break;
  429.     case ROCK_CLASS:
  430.         switch (otmp->otyp) {
  431.             case STATUE:
  432.             if (rn2(level_difficulty()/2 + 10) > 10) {
  433.                 struct obj *book;
  434.                 book = mkobj(SPBOOK_CLASS,FALSE);
  435.                 otmp->cobj = book;
  436.             }
  437.             /* overridden by mkcorpstat() */
  438.             otmp->corpsenm = rndmonnum();
  439.         }
  440.         break;
  441.     case GOLD_CLASS:
  442.         break;    /* do nothing */
  443.     default:
  444.         impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, objects[otmp->otyp].oc_class);
  445.         return (struct obj *)0;
  446.     }
  447.     /* unique objects may have an associated artifact entry */
  448.     if (objects[otyp].oc_unique && !otmp->oartifact)
  449.         otmp = mk_artifact(otmp, (aligntyp)A_NONE);
  450.     otmp->owt = weight(otmp);
  451.     return(otmp);
  452. }
  453.  
  454. void
  455. bless(otmp)
  456. register struct obj *otmp;
  457. {
  458.     otmp->cursed = 0;
  459.     otmp->blessed = 1;
  460.     if (otmp->otyp == LUCKSTONE
  461.         || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
  462.         int luckbon = stone_luck(TRUE);
  463.         if(!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
  464.         else if (luckbon >= 0) u.moreluck = LUCKADD;
  465.         else u.moreluck = -LUCKADD;
  466.     } else if (otmp->otyp == BAG_OF_HOLDING)
  467.         otmp->owt = weight(otmp);
  468.     return;
  469. }
  470.  
  471. void
  472. unbless(otmp)
  473. register struct obj *otmp;
  474. {
  475.     otmp->blessed = 0;
  476.     if (otmp->otyp == LUCKSTONE
  477.         || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
  478.         int luckbon = stone_luck(TRUE);
  479.         if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
  480.         else if (luckbon >= 0) u.moreluck = LUCKADD;
  481.         else u.moreluck = -LUCKADD;
  482.     } else if (otmp->otyp == BAG_OF_HOLDING)
  483.         otmp->owt = weight(otmp);
  484. }
  485.  
  486. void
  487. curse(otmp)
  488. register struct obj *otmp;
  489. {
  490.     otmp->blessed = 0;
  491.     otmp->cursed = 1;
  492.     if (otmp->otyp == LUCKSTONE
  493.         || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
  494.         int luckbon = stone_luck(TRUE);
  495.         if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
  496.         else if (luckbon >= 0) u.moreluck = LUCKADD;
  497.         else u.moreluck = -LUCKADD;
  498.     } else if (otmp->otyp == BAG_OF_HOLDING)
  499.         otmp->owt = weight(otmp);
  500.     return;
  501. }
  502.  
  503. void
  504. uncurse(otmp)
  505. register struct obj *otmp;
  506. {
  507.     otmp->cursed = 0;
  508.     if (otmp->otyp == LUCKSTONE
  509.         || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
  510.         int luckbon = stone_luck(TRUE);
  511.         if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
  512.         else if (luckbon >= 0) u.moreluck = LUCKADD;
  513.         else u.moreluck = -LUCKADD;
  514.     } else if (otmp->otyp == BAG_OF_HOLDING)
  515.         otmp->owt = weight(otmp);
  516. }
  517.  
  518. #endif /* OVLB */
  519. #ifdef OVL1
  520. void
  521. blessorcurse(otmp, chance)
  522. register struct obj *otmp;
  523. register int chance;
  524. {
  525.     if(otmp->blessed || otmp->cursed) return;
  526.  
  527.     if(!rn2(chance))
  528.         if(!rn2(2)) {
  529.         curse(otmp);
  530.         } else {
  531.         bless(otmp);
  532.         }
  533.     return;
  534. }
  535.  
  536. #endif /* OVL1 */
  537. #ifdef OVLB
  538.  
  539. int
  540. bcsign(otmp)
  541. register struct obj *otmp;
  542. {
  543.     return(!!otmp->blessed - !!otmp->cursed);
  544. }
  545.  
  546. #endif /* OVLB */
  547. #ifdef OVL0
  548.  
  549. /*
  550.  *  Calculate the weight of the given object.  This will recursively follow
  551.  *  and calculate the weight of any containers.
  552.  *
  553.  *  Note:  It is possible to end up with an incorrect weight if some part
  554.  *       of the code messes with a contained object and doesn't update the
  555.  *       container's weight.
  556.  */
  557. int
  558. weight(obj)
  559. register struct obj *obj;
  560. {
  561.     int wt = objects[obj->otyp].oc_weight;
  562.  
  563.     if (Is_container(obj) || obj->otyp == STATUE) {
  564.         struct obj *contents;
  565.         register int cwt = 0;
  566.  
  567.         if (obj->otyp == STATUE && obj->corpsenm > -1)
  568.             wt = (int)obj->quan *
  569.              ((int)mons[obj->corpsenm].cwt * 3 / 2);
  570.  
  571.         for(contents=obj->cobj; contents; contents=contents->nobj)
  572.             cwt += weight(contents);
  573.         /*
  574.          *  The weight of bags of holding is calculated as the weight
  575.          *  of the bag plus the weight of the bag's contents modified
  576.          *  as follows:
  577.          *
  578.          *    Bag status    Weight of contents
  579.          *    ----------    ------------------
  580.          *    cursed            2x
  581.          *    blessed            x/4 + 1
  582.          *    otherwise        x/2 + 1
  583.          *
  584.          *  The macro DELTA_CWT in pickup.c also implements these
  585.          *  weight equations.
  586.          *
  587.          *  Note:  The above checks are performed in the given order.
  588.          *       this means that if an object is both blessed and
  589.          *       cursed (not supposed to happen), it will be treated
  590.          *       as cursed.
  591.          */
  592.         if (obj->otyp == BAG_OF_HOLDING)
  593.             cwt = obj->cursed ? (cwt * 2) :
  594.                     (1 + (cwt / (obj->blessed ? 4 : 2)));
  595.  
  596.         return wt + cwt;
  597.     }
  598.     if (obj->otyp == CORPSE && obj->corpsenm > -1)
  599.         return (int)obj->quan * mons[obj->corpsenm].cwt;
  600.     else if (obj->otyp == GOLD_PIECE)
  601.         return (int)((obj->quan + 500L) / 1000L);
  602.     return(wt ? wt*(int)obj->quan : ((int)obj->quan + 1)>>1);
  603. }
  604.  
  605. #endif /* OVL0 */
  606. #ifdef OVLB
  607.  
  608. void
  609. mkgold(amount, x, y)
  610. long amount;
  611. int x, y;
  612. {
  613.     register struct obj *gold = g_at(x,y);
  614.  
  615.     if (amount <= 0L) amount = (long)(1 + rnd(level_difficulty()+2) * rnd(30));
  616.     if (gold) {
  617.     gold->quan += amount;
  618.     } else {
  619.     gold = mksobj_at(GOLD_PIECE,x,y,TRUE);
  620.     gold->quan = amount;
  621.     }
  622.     gold->owt = weight(gold);
  623. }
  624.  
  625. #endif /* OVLB */
  626. #ifdef OVL1
  627. struct obj *
  628. mkcorpstat(objtype, ptr, x, y, init)
  629. int objtype;    /* CORPSE or STATUE */
  630. register struct permonst *ptr;
  631. int x, y;
  632. boolean init;
  633. {
  634.     register struct obj *otmp;
  635.  
  636.     if(objtype != CORPSE && objtype != STATUE)
  637.         impossible("making corpstat type %d", objtype);
  638.     otmp = mksobj_at(objtype, x, y, init);
  639.     if(otmp)  {
  640.         if(ptr)    otmp->corpsenm = monsndx(ptr);
  641.         else    otmp->corpsenm = rndmonnum();
  642.         otmp->owt = weight(otmp);
  643.     }
  644.     return(otmp);
  645. }
  646.  
  647. #endif /* OVL1 */
  648. #ifdef OVLB
  649. struct obj *
  650. mk_tt_object(objtype, x, y)
  651. int objtype; /* CORPSE or STATUE */
  652. register int x, y;
  653. {
  654.     register struct obj *otmp;
  655.  
  656.     /* player statues never contain books */
  657.     if ((otmp = mksobj_at(objtype,x,y,FALSE)) != 0)
  658.         otmp = tt_oname(otmp);
  659.     return(otmp);
  660. }
  661.  
  662. /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */
  663. struct obj *
  664. mk_named_object(objtype, ptr, x, y, nm, lth)
  665. int objtype; /* CORPSE or STATUE */
  666. register struct permonst *ptr;
  667. int x, y;
  668. char * nm;
  669. register int lth;
  670. {
  671.     struct obj *otmp;
  672.  
  673.     otmp = mkcorpstat(objtype,ptr,x,y,(objtype != STATUE));
  674.     if (lth > 0) {
  675.         /* Note: oname() is safe since otmp is first in both chains */
  676.         otmp = oname(otmp, nm, FALSE);
  677.         fobj = otmp;
  678.         level.objects[x][y] = otmp;
  679.         if (is_pool(x,y)) water_damage(otmp,TRUE);
  680.     }
  681.     return(otmp);
  682. }
  683.  
  684. boolean
  685. is_flammable(otmp)
  686. register struct obj *otmp;
  687. {
  688.     int otyp = otmp->otyp;
  689.  
  690.     if (objects[otyp].oc_oprop == FIRE_RES) return FALSE;
  691.  
  692.     return((objects[otyp].oc_material == WOOD ||
  693.             objects[otyp].oc_material == 0));
  694.  
  695. }
  696.  
  697. #endif /* OVLB */
  698. #ifdef OVL1
  699.  
  700. /*
  701.  * These routines maintain the single-linked lists headed in level.objects[][]
  702.  * and threaded through the nexthere fields in the object-instance structure.
  703.  */
  704.  
  705. void
  706. place_object(otmp, x, y)
  707. /* put an object on top of the pile at the given location */
  708. register struct obj *otmp;
  709. int x, y;
  710. {
  711.     register struct obj *otmp2 = level.objects[x][y];
  712.  
  713.     if (otmp->otyp == BOULDER) block_point(x,y);    /* vision */
  714.  
  715.     if (otmp2 && (otmp2->otyp == BOULDER)) {
  716.     otmp->nexthere = otmp2->nexthere;
  717.     otmp2->nexthere = otmp;
  718.     } else {
  719.     otmp->nexthere = otmp2;
  720.     level.objects[x][y] = otmp;
  721.     }
  722.     if (is_pool(x,y)) water_damage(otmp,TRUE);
  723.  
  724.     /* set the new object's location */
  725.     otmp->ox = x;
  726.     otmp->oy = y;
  727. }
  728.  
  729. #endif /* OVL1 */
  730. #ifdef OVLB
  731. void
  732. remove_object(otmp)
  733. register struct obj *otmp;
  734. {
  735.     register struct obj *odel;
  736.  
  737.     if (otmp->otyp == BOULDER) unblock_point(otmp->ox,otmp->oy); /* vision */
  738.  
  739.     if (otmp == level.objects[otmp->ox][otmp->oy])
  740.     level.objects[otmp->ox][otmp->oy] = otmp->nexthere;
  741.     else
  742.     for (odel = level.objects[otmp->ox][otmp->oy];
  743.                             odel; odel = odel->nexthere)
  744.         if (odel->nexthere == otmp) {
  745.         odel->nexthere = otmp->nexthere;
  746.         break;
  747.         }
  748. }
  749.  
  750. void
  751. move_object(otmp, x, y)
  752. register struct obj *otmp;
  753. int x, y;
  754. {
  755.     remove_object(otmp);
  756.     place_object(otmp, x, y);
  757. }
  758.  
  759. #endif /* OVLB */
  760.  
  761. /*mkobj.c*/
  762.